﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;

namespace Wpf1
{
    [SuppressUnmanagedCodeSecurity]
    public static class ConsoleHelper
    {
        [DllImport("Kernel32")]
        private static extern bool AllocConsole();
        [DllImport("Kernel32")]
        private static extern bool FreeConsole();
        [DllImport("Kernel32")]
        private static extern IntPtr GetConsoleWindow();
        [DllImport("Kernel32")]
        private static extern IntPtr GetConsoleOutputCP();

        public static bool HasConsole { get { return GetConsoleOutputCP() != IntPtr.Zero; } }
        public static void Show()
        {
            if (HasConsole) return;
            AllocConsole();
            InvalidateOutAndError();
        }
        public static void Hide()
        {
            if (!HasConsole) return;
            SetOutAndErrorNull();
            FreeConsole();
        }
        public static void Toggle()
        {
            if (HasConsole)
                Hide();
            else
                Show();
        }
        static void InvalidateOutAndError()
        {
            var type = typeof (Console);
            const BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic;
            var fOut = type.GetField("_out", flags);
            var fError = type.GetField("_error", flags);
            var mInitializeStdOutError = type.GetMethod("InitializeStdOutError", flags);
            fOut.SetValue(null, null);
            fError.SetValue(null, null);
            mInitializeStdOutError.Invoke(null, new object[] {true});
        }
        static void SetOutAndErrorNull()
        {
            Console.SetOut(TextWriter.Null);
            Console.SetError(TextWriter.Null);
        }
    }
}
